home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / ControlSequences.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  14KB  |  834 lines

  1. /*
  2. **    ControlSequences.c
  3. **
  4. **    Routines that handle control sequences
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* CallMenu(STRPTR Name,ULONG Code):
  17.      *
  18.      *    Call a menu function either through the name of the corresponding
  19.      *    menu item or a menu number.
  20.      */
  21.  
  22. STATIC VOID
  23. CallMenu(STRPTR Name,ULONG Code)
  24. {
  25.     LONG MenuNum = -1,Item = 0,Sub = 0,i;
  26.  
  27.         /* Are we to look for a name? */
  28.  
  29.     if(Name)
  30.     {
  31.         LONG Len = strlen(Name);
  32.  
  33.             /* Scan the menu list... */
  34.  
  35.         for(i = 0 ; TermMenu[i].nm_Type != NM_END ; i++)
  36.         {
  37.             switch(TermMenu[i].nm_Type)
  38.             {
  39.                 case NM_TITLE:
  40.  
  41.                     MenuNum++;
  42.                     Item = Sub = 0;
  43.                     break;
  44.  
  45.                 case NM_ITEM:
  46.  
  47.                     Sub = 0;
  48.                     break;
  49.             }
  50.  
  51.                 /* Did we get a valid name string? */
  52.  
  53.             if(TermMenu[i].nm_Label != NM_BARLABEL)
  54.             {
  55.                     /* Does the name match our template? */
  56.  
  57.                 if(!Strnicmp(TermMenu[i].nm_Label,Name,Len))
  58.                 {
  59.                     struct MenuItem *MenuItem = ItemAddress(Menu,FULLMENUNUM(MenuNum,Item,Sub));
  60.  
  61.                     if(MenuItem && (MenuItem->Flags & ITEMENABLED))
  62.                         HandleMenuCode((ULONG)TermMenu[i].nm_UserData,NULL);
  63.  
  64.                     break;
  65.                 }
  66.             }
  67.  
  68.             switch(TermMenu[i].nm_Type)
  69.             {
  70.                 case NM_ITEM:
  71.  
  72.                     Item++;
  73.                     break;
  74.  
  75.                 case NM_SUB:
  76.  
  77.                     Sub++;
  78.                     break;
  79.             }
  80.         }
  81.     }
  82.     else
  83.     {
  84.         LONG    TheMenu    =  Code % 100,
  85.                 TheItem    = (Code / 100) % 100,
  86.                 TheSub    =  Code / 10000;
  87.  
  88.             /* Scan the menu list... */
  89.  
  90.         for(i = 0 ; TermMenu[i].nm_Type != NM_END ; i++)
  91.         {
  92.             switch(TermMenu[i].nm_Type)
  93.             {
  94.                 case NM_TITLE:
  95.  
  96.                     MenuNum++;
  97.                     Item = Sub = 0;
  98.                     break;
  99.  
  100.                 case NM_ITEM:
  101.  
  102.                     Sub = 0;
  103.                     break;
  104.             }
  105.  
  106.                 /* Is it the menu number we want? */
  107.  
  108.             if(TheMenu == MenuNum && TheItem == Item && TheSub == Sub)
  109.             {
  110.                 if(TermMenu[i].nm_Label != NM_BARLABEL)
  111.                 {
  112.                     struct MenuItem *MenuItem = ItemAddress(Menu,FULLMENUNUM(MenuNum,Item,Sub));
  113.  
  114.                     if(MenuItem && (MenuItem->Flags & ITEMENABLED))
  115.                         HandleMenuCode((ULONG)TermMenu[i].nm_UserData,NULL);
  116.                 }
  117.  
  118.                 break;
  119.             }
  120.  
  121.             switch(TermMenu[i].nm_Type)
  122.             {
  123.                 case NM_ITEM:
  124.  
  125.                     Item++;
  126.                     break;
  127.  
  128.                 case NM_SUB:
  129.  
  130.                     Sub++;
  131.                     break;
  132.             }
  133.         }
  134.     }
  135. }
  136.  
  137.     /* CommonControlProcessing(STRPTR String,BOOL LocalOnly):
  138.      *
  139.      *    Processes a control sequenced; effects are either limited
  140.      *    to the console window or will affect the serial interface
  141.      *    and the main program body.
  142.      */
  143.  
  144. STATIC VOID
  145. CommonControlProcessing(STRPTR String,BOOL LocalOnly)
  146. {
  147.     UBYTE LocalBuffer[256];
  148.     BOOL GotControl,GotEscape;
  149.     SENDLINE SendLineLocal;
  150.     LONG Count,i,Len;
  151.     UBYTE c;
  152.  
  153.     if(LocalOnly)
  154.         SendLineLocal = (SENDLINE)ConProcess;
  155.     else
  156.         SendLineLocal = (SENDLINE)SendLine;
  157.  
  158.     GotControl = GotEscape = FALSE;
  159.     Count = 0;
  160.  
  161.         /* Scan the string. */
  162.  
  163.     Len = strlen(String);
  164.  
  165.     for(i = 0 ; i < Len ; i++)
  166.     {
  167.             /* We are looking for plain characters
  168.              * and the control ('\') and escape
  169.              * ('^') characters.
  170.              */
  171.  
  172.         if(!GotControl && !GotEscape)
  173.         {
  174.             switch(String[i])
  175.             {
  176.                     /* Got a control character,
  177.                      * the next byte will probably be
  178.                      * a command sequence.
  179.                      */
  180.  
  181.                 case '\\':
  182.  
  183.                     GotControl = TRUE;
  184.                     break;
  185.  
  186.                     /* Got an escape character,
  187.                      * the next byte will be some
  188.                      * kind of control character
  189.                      * (such as XON, XOF, bell, etc.).
  190.                      */
  191.  
  192.                 case '^':
  193.  
  194.                     GotEscape = TRUE;
  195.                     break;
  196.  
  197.                     /* This tells us to wait another
  198.                      * second before continuing with
  199.                      * the scanning.
  200.                      */
  201.  
  202.                 case '~':
  203.  
  204.                     if(Count)
  205.                     {
  206.                         (*SendLineLocal)(LocalBuffer,Count);
  207.                         Count = 0;
  208.                     }
  209.  
  210.                     DelayTime(0,MILLION / 2);
  211.  
  212.                     if(!LocalOnly)
  213.                         RunJob(SerialJob);
  214.  
  215.                     break;
  216.  
  217.                     /* Stuff the character into the
  218.                      * buffer.
  219.                      */
  220.  
  221.                 default:
  222.  
  223.                     LocalBuffer[Count++] = String[i];
  224.                     break;
  225.             }
  226.         }
  227.         else
  228.         {
  229.                 /* Convert the character to a control
  230.                  * style character (^C, etc.).
  231.                  */
  232.  
  233.             if(GotEscape)
  234.             {
  235.                 if(ToUpper(String[i]) >= 'A' && ToUpper(String[i]) <= '_')
  236.                     LocalBuffer[Count++] = ToUpper(String[i]) - '@';
  237.                 else
  238.                     LocalBuffer[Count++] = String[i];
  239.  
  240.                 GotEscape = FALSE;
  241.             }
  242.  
  243.                 /* The next character represents a command. */
  244.  
  245.             if(GotControl)
  246.             {
  247.                 switch(ToUpper(String[i]))
  248.                 {
  249.                         /* Fall back to default send mode. */
  250.  
  251.                     case '0':
  252.  
  253.                         if(Count)
  254.                         {
  255.                             (*SendLineLocal)(LocalBuffer,Count);
  256.  
  257.                             Count = 0;
  258.                         }
  259.  
  260.                         if(!LocalOnly)
  261.                             SendLineLocal = (SENDLINE)SendLine;
  262.  
  263.                         break;
  264.  
  265.                         /* Select `direct' send mode. */
  266.  
  267.                     case '1':
  268.  
  269.                         if(Count)
  270.                         {
  271.                             (*SendLineLocal)(LocalBuffer,Count);
  272.  
  273.                             Count = 0;
  274.                         }
  275.  
  276.                         if(!LocalOnly)
  277.                             SendLineLocal = (SENDLINE)SendLineSimple;
  278.  
  279.                         break;
  280.  
  281.                         /* Select `echo' send mode. */
  282.  
  283.                     case '2':
  284.  
  285.                         if(Count)
  286.                         {
  287.                             (*SendLineLocal)(LocalBuffer,Count);
  288.  
  289.                             Count = 0;
  290.                         }
  291.  
  292.                         if(!LocalOnly)
  293.                         {
  294.                             if(Config->ClipConfig->SendTimeout)
  295.                                 SendLineLocal = (SENDLINE)SendLineEcho;
  296.                             else
  297.                                 SendLineLocal = (SENDLINE)SendLineSimple;
  298.                         }
  299.  
  300.                         break;
  301.  
  302.                         /* Select `any echo' send mode. */
  303.  
  304.                     case '3':
  305.  
  306.                         if(Count)
  307.                         {
  308.                             (*SendLineLocal)(LocalBuffer,Count);
  309.  
  310.                             Count = 0;
  311.                         }
  312.  
  313.                         if(!LocalOnly)
  314.                         {
  315.                             if(Config->ClipConfig->SendTimeout)
  316.                                 SendLineLocal = (SENDLINE)SendLineAnyEcho;
  317.                             else
  318.                                 SendLineLocal = (SENDLINE)SendLineSimple;
  319.                         }
  320.  
  321.                         break;
  322.  
  323.                         /* Select `prompt' send mode. */
  324.  
  325.                     case '4':
  326.  
  327.                         if(Count)
  328.                         {
  329.                             (*SendLineLocal)(LocalBuffer,Count);
  330.  
  331.                             Count = 0;
  332.                         }
  333.  
  334.                         if(!LocalOnly)
  335.                         {
  336.                             if(Config->ClipConfig->SendTimeout)
  337.                                 SendLineLocal = (SENDLINE)SendLinePrompt;
  338.                             else
  339.                                 SendLineLocal = (SENDLINE)SendLineSimple;
  340.                         }
  341.  
  342.                         break;
  343.  
  344.                         /* Select `delay' send mode. */
  345.  
  346.                     case '5':
  347.  
  348.                         if(Count)
  349.                         {
  350.                             (*SendLineLocal)(LocalBuffer,Count);
  351.  
  352.                             Count = 0;
  353.                         }
  354.  
  355.                         if(!LocalOnly)
  356.                         {
  357.                             if(Config->ClipConfig->LineDelay || Config->ClipConfig->CharDelay)
  358.                                 SendLineLocal = (SENDLINE)SendLineDelay;
  359.                             else
  360.                                 SendLineLocal = (SENDLINE)SendLineSimple;
  361.                         }
  362.  
  363.                         break;
  364.  
  365.                         /* Select `keyboard' send mode. */
  366.  
  367.                     case '6':
  368.  
  369.                         if(Count)
  370.                         {
  371.                             (*SendLineLocal)(LocalBuffer,Count);
  372.  
  373.                             Count = 0;
  374.                         }
  375.  
  376.                         if(!LocalOnly)
  377.                             SendLineLocal = (SENDLINE)SendLineKeyDelay;
  378.  
  379.                         break;
  380.  
  381.                         /* Translate code. */
  382.  
  383.                     case '*':
  384.  
  385.                         i++;
  386.  
  387.                         while(i < Len && String[i] == ' ')
  388.                             i++;
  389.  
  390.                         if(i < Len)
  391.                         {
  392.                             UBYTE DummyBuffer[5];
  393.                             LONG j = 0,Char;
  394.  
  395.                             if(String[i] >= '0' && String[i] <= '9')
  396.                             {
  397.                                 while(j < 3 && i < Len)
  398.                                 {
  399.                                     Char = String[i++];
  400.  
  401.                                     if(Char >= '0' && Char <= '9')
  402.                                         DummyBuffer[j++] = Char;
  403.                                     else
  404.                                     {
  405.                                         i--;
  406.  
  407.                                         break;
  408.                                     }
  409.                                 }
  410.                             }
  411.                             else
  412.                             {
  413.                                 while(j < 4 && i < Len)
  414.                                 {
  415.                                     Char = ToLower(String[i++]);
  416.  
  417.                                     if((Char >= '0' && Char <= '9') || (Char >= 'a' && Char <= 'z'))
  418.                                         DummyBuffer[j++] = Char;
  419.                                     else
  420.                                     {
  421.                                         i--;
  422.  
  423.                                         break;
  424.                                     }
  425.                                 }
  426.                             }
  427.  
  428.                             DummyBuffer[j] = 0;
  429.  
  430.                             LocalBuffer[Count++] = NameToCode(DummyBuffer);
  431.                         }
  432.  
  433.                         i--;
  434.  
  435.                         break;
  436.  
  437.                         /* Execute an AmigaDOS command. */
  438.  
  439.                     case 'D':
  440.  
  441.                         if(!InRexx && !LocalOnly)
  442.                             LaunchCommandAsync(&String[i + 1]);
  443.  
  444.                         return;
  445.  
  446.                         /* Execute an ARexx command. */
  447.  
  448.                     case 'A':
  449.  
  450.                         if(!InRexx && !LocalOnly)
  451.                             LaunchRexxAsync(&String[i + 1]);
  452.  
  453.                         return;
  454.  
  455.                         /* Add the control character ('\'). */
  456.  
  457.                     case '\\':
  458.  
  459.                         LocalBuffer[Count++] = '\\';
  460.                         break;
  461.  
  462.                         /* This is a backspace. */
  463.  
  464.                     case 'B':
  465.  
  466.                         LocalBuffer[Count++] = '\b';
  467.                         break;
  468.  
  469.                         /* This is a form feed. */
  470.  
  471.                     case 'F':
  472.  
  473.                         LocalBuffer[Count++] = '\f';
  474.                         break;
  475.  
  476.                         /* This is a line feed. */
  477.  
  478.                     case 'N':
  479.  
  480.                         if(String[i] == 'n' || Config->TerminalConfig->SendLF == EOL_LF)
  481.                             LocalBuffer[Count++] = '\n';
  482.                         else
  483.                         {
  484.                             STRPTR What;
  485.                             LONG j;
  486.  
  487.                             switch(Config->TerminalConfig->SendLF)
  488.                             {
  489.                                 case EOL_LFCR:
  490.  
  491.                                     What = "\n\r";
  492.                                     break;
  493.  
  494.                                 case EOL_CRLF:
  495.  
  496.                                     What = "\r\n";
  497.                                     break;
  498.  
  499.                                 case EOL_CR:
  500.  
  501.                                     What = "\r";
  502.                                     break;
  503.                             }
  504.  
  505.                             for(j = 0 ; What[j] ; j++)
  506.                             {
  507.                                 LocalBuffer[Count++] = What[j];
  508.  
  509.                                     /* If the buffer is full, release it. */
  510.  
  511.                                 if(Count == sizeof(LocalBuffer))
  512.                                 {
  513.                                     (*SendLineLocal)(LocalBuffer,Count);
  514.  
  515.                                     Count = 0;
  516.                                 }
  517.                             }
  518.                         }
  519.  
  520.                         break;
  521.  
  522.                         /* Send the current password. */
  523.  
  524.                     case 'P':
  525.  
  526.                         if(Password[0])
  527.                         {
  528.                             if(Count)
  529.                             {
  530.                                 (*SendLineLocal)(LocalBuffer,Count);
  531.  
  532.                                 Count = 0;
  533.                             }
  534.  
  535.                             (*SendLineLocal)(Password,strlen(Password));
  536.                         }
  537.  
  538.                         break;
  539.  
  540.                         /* This is a carriage return. */
  541.  
  542.                     case 'R':
  543.  
  544.                         if(String[i] == 'r' || Config->TerminalConfig->SendCR == EOL_CR)
  545.                             LocalBuffer[Count++] = '\r';
  546.                         else
  547.                         {
  548.                             STRPTR What;
  549.                             LONG j;
  550.  
  551.                             switch(Config->TerminalConfig->SendCR)
  552.                             {
  553.                                 case EOL_LFCR:
  554.  
  555.                                     What = "\n\r";
  556.                                     break;
  557.  
  558.                                 case EOL_CRLF:
  559.  
  560.                                     What = "\r\n";
  561.                                     break;
  562.  
  563.                                 case EOL_LF:
  564.  
  565.                                     What = "\n";
  566.                                     break;
  567.                             }
  568.  
  569.                             for(j = 0 ; What[j] ; j++)
  570.                             {
  571.                                 LocalBuffer[Count++] = What[j];
  572.  
  573.                                     /* If the buffer is full, release it. */
  574.  
  575.                                 if(Count == sizeof(LocalBuffer))
  576.                                 {
  577.                                     (*SendLineLocal)(LocalBuffer,Count);
  578.  
  579.                                     Count = 0;
  580.                                 }
  581.                             }
  582.                         }
  583.  
  584.                         break;
  585.  
  586.                         /* This is a tab. */
  587.  
  588.                     case 'T':
  589.  
  590.                         LocalBuffer[Count++] = '\t';
  591.                         break;
  592.  
  593.                         /* Send the current user name. */
  594.  
  595.                     case 'U':
  596.  
  597.                         if(UserName[0])
  598.                         {
  599.                             if(Count)
  600.                             {
  601.                                 (*SendLineLocal)(LocalBuffer,Count);
  602.  
  603.                                 Count = 0;
  604.                             }
  605.  
  606.                             (*SendLineLocal)(UserName,strlen(UserName));
  607.                         }
  608.  
  609.                         break;
  610.  
  611.                         /* Send a break across the serial line. */
  612.  
  613.                     case 'X':
  614.  
  615.                         if(Count)
  616.                         {
  617.                             (*SendLineLocal)(LocalBuffer,Count);
  618.  
  619.                             Count = 0;
  620.                         }
  621.  
  622.                         if(!LocalOnly)
  623.                             SendBreak();
  624.  
  625.                         break;
  626.  
  627.                         /* Feed the contents of the
  628.                          * clipboard into the input
  629.                          * stream.
  630.                          */
  631.  
  632.                     case 'I':
  633.  
  634.                         if(Count)
  635.                             (*SendLineLocal)(LocalBuffer,Count);
  636.  
  637.                         Count = LoadClip(LocalBuffer,sizeof(LocalBuffer));
  638.  
  639.                         break;
  640.  
  641.                         /* Send a string to the clipboard. */
  642.  
  643.                     case 'G':
  644.  
  645.                         if(String[i + 1])
  646.                             SaveClip(&String[i + 1],strlen(&String[i + 1]));
  647.  
  648.                         return;
  649.  
  650.                         /* Send a string to the clipboard. */
  651.  
  652.                     case 'H':
  653.  
  654.                         if(String[i + 1])
  655.                             AddClip(&String[i + 1],strlen(&String[i + 1]));
  656.  
  657.                         return;
  658.  
  659.                         /* Produce the escape character. */
  660.  
  661.                     case 'E':
  662.  
  663.                         LocalBuffer[Count++] = ESC;
  664.                         break;
  665.  
  666.                         /* Call a menu item. */
  667.  
  668.                     case 'C':
  669.  
  670.                         i++;
  671.  
  672.                             /* Scan for a menu number or
  673.                              * a single quote...
  674.                              */
  675.  
  676.                         while(i < Len)
  677.                         {
  678.                             if(String[i] >= '0' && String[i] <= '9')
  679.                                 break;
  680.  
  681.                             if(String[i] == '\'')
  682.                                 break;
  683.  
  684.                             if(String[i] != ' ')
  685.                                 break;
  686.  
  687.                             i++;
  688.                         }
  689.  
  690.                         if(i < Len)
  691.                         {
  692.                             UBYTE DummyBuffer[sizeof(LocalBuffer)];
  693.  
  694.                                 /* Did we get a quote? */
  695.  
  696.                             if(String[i] == '\'')
  697.                             {
  698.                                 LONG Start = ++i;
  699.  
  700.                                 if(String[Start])
  701.                                 {
  702.                                     LONG Length;
  703.  
  704.                                     while(i < Len)
  705.                                     {
  706.                                         if(String[i] != '\'')
  707.                                             i++;
  708.                                         else
  709.                                             break;
  710.                                     }
  711.  
  712.                                     if(String[i] == '\'')
  713.                                         Length = i - Start;
  714.                                     else
  715.                                         Length = i - Start + 1;
  716.  
  717.                                     CopyMem(&String[Start],DummyBuffer,Length);
  718.  
  719.                                     DummyBuffer[Length] = 0;
  720.  
  721.                                     CallMenu(DummyBuffer,0);
  722.                                 }
  723.                             }
  724.                             else
  725.                             {
  726.                                 if(String[i] >= '0' && String[i] <= '9')
  727.                                 {
  728.                                     LONG Start = i,Length;
  729.  
  730.                                     while(i < Len)
  731.                                     {
  732.                                         if(String[i] >= '0' && String[i] <= '9')
  733.                                             i++;
  734.                                         else
  735.                                             break;
  736.                                     }
  737.  
  738.                                     if(i == Start)
  739.                                         Length = 1;
  740.                                     else
  741.                                         Length = i - Start;
  742.  
  743.                                     CopyMem(&String[Start],DummyBuffer,Length);
  744.  
  745.                                     DummyBuffer[Length] = 0;
  746.  
  747.                                     CallMenu(NULL,Atol(DummyBuffer));
  748.                                 }
  749.                             }
  750.                         }
  751.  
  752.                         break;
  753.  
  754.                         /* Insert the current dialing mode suffix. */
  755.  
  756.                     case 'W':
  757.  
  758.                         switch(Config->ModemConfig->DialMode)
  759.                         {
  760.                             case DIALMODE_TONE:
  761.  
  762.                                 c = 'T';
  763.                                 break;
  764.  
  765.                             case DIALMODE_MODEM:
  766.  
  767.                                 c = 'M';
  768.                                 break;
  769.  
  770.                             case DIALMODE_ISDN:
  771.  
  772.                                 c = 'I';
  773.                                 break;
  774.  
  775.                             default:
  776.  
  777.                                 c = 'P';    /* Pulse */
  778.                                 break;
  779.                         }
  780.  
  781.                         LocalBuffer[Count++] = c;
  782.  
  783.                         break;
  784.  
  785.                         /* Stuff the character into the buffer. */
  786.  
  787.                     default:
  788.  
  789.                         LocalBuffer[Count++] = String[i];
  790.                         break;
  791.                 }
  792.  
  793.                 GotControl = FALSE;
  794.             }
  795.         }
  796.  
  797.             /* If the buffer is full, release it. */
  798.  
  799.         if(Count == sizeof(LocalBuffer))
  800.         {
  801.             (*SendLineLocal)(LocalBuffer,Count);
  802.  
  803.             Count = 0;
  804.         }
  805.     }
  806.  
  807.     if(Count)
  808.         (*SendLineLocal)(LocalBuffer,Count);
  809. }
  810.  
  811.     /* SerialCommand(STRPTR String):
  812.      *
  813.      *    Send a command string to the serial line and
  814.      *    interprete the control sequences.
  815.      */
  816.  
  817. VOID
  818. SerialCommand(STRPTR String)
  819. {
  820.     CommonControlProcessing(String,FALSE);
  821. }
  822.  
  823.     /* ConsoleCommand(STRPTR String):
  824.      *
  825.      *    Just like SerialCommand(), but addresses the local
  826.      *    terminal side.
  827.      */
  828.  
  829. VOID
  830. ConsoleCommand(STRPTR String)
  831. {
  832.     CommonControlProcessing(String,TRUE);
  833. }
  834.